deploy: SELinux-relabel installed kernel/initramfs data
authorColin Walters <walters@verbum.org>
Fri, 2 Feb 2018 18:46:15 +0000 (13:46 -0500)
committerAtomic Bot <atomic-devel@projectatomic.io>
Fri, 2 Feb 2018 22:32:49 +0000 (22:32 +0000)
When we changed around the kernel location in rpm-ostree, we
started installing the kernel into `/boot` as `modules_object_t`,
and the current policy didn't permit that.  For maximum compatibility,
relabel installed kernel/initramfs/dtb as `boot_t`.

https://bugzilla.redhat.com/show_bug.cgi?id=1536991

Closes: #1444
Approved by: jlebon

src/libostree/ostree-sysroot-deploy.c
tests/installed/itest-deploy-selinux.sh

index 2754b394b02558144c9b3d517de70c71fce3ddff..4284b5ae91824410d329fa6f35a66d4d29988141 100644 (file)
@@ -99,20 +99,38 @@ sysroot_flags_to_copy_flags (GLnxFileCopyFlags defaults,
  * hardlink if we're on the same partition.
  */
 static gboolean
-hardlink_or_copy_at (int         src_dfd,
-                     const char *src_subpath,
-                     int         dest_dfd,
-                     const char *dest_subpath,
-                     OstreeSysrootDebugFlags flags,
-                     GCancellable  *cancellable,
-                     GError       **error)
+install_into_boot (OstreeSePolicy *sepolicy,
+                   int         src_dfd,
+                   const char *src_subpath,
+                   int         dest_dfd,
+                   const char *dest_subpath,
+                   OstreeSysrootDebugFlags flags,
+                   GCancellable  *cancellable,
+                   GError       **error)
 {
   if (linkat (src_dfd, src_subpath, dest_dfd, dest_subpath, 0) != 0)
     {
       if (G_IN_SET (errno, EMLINK, EXDEV))
-        return glnx_file_copy_at (src_dfd, src_subpath, NULL, dest_dfd, dest_subpath,
-                                  sysroot_flags_to_copy_flags (0, flags),
-                                  cancellable, error);
+        {
+          /* Be sure we relabel when copying the kernel, as in current
+           * e.g. Fedora it might be labeled module_object_t or usr_t,
+           * but policy may not allow other processes to read from that
+           * like kdump.
+           * See also https://github.com/fedora-selinux/selinux-policy/commit/747f4e6775d773ab74efae5aa37f3e5e7f0d4aca
+           * This means we also drop xattrs but...I doubt anyone uses
+           * non-SELinux xattrs for the kernel anyways aside from perhaps
+           * IMA but that's its own story.
+           */
+          g_auto(OstreeSepolicyFsCreatecon) fscreatecon = { 0, };
+          const char *boot_path = glnx_strjoina ("/boot/", glnx_basename (dest_subpath));
+          if (!_ostree_sepolicy_preparefscreatecon (&fscreatecon, sepolicy,
+                                                    boot_path, S_IFREG | 0644,
+                                                    error))
+            return FALSE;
+          return glnx_file_copy_at (src_dfd, src_subpath, NULL, dest_dfd, dest_subpath,
+                                    GLNX_FILE_COPY_NOXATTRS,
+                                    cancellable, error);
+        }
       else
         return glnx_throw_errno_prefix (error, "linkat(%s)", dest_subpath);
     }
@@ -1617,6 +1635,11 @@ install_deployment_kernel (OstreeSysroot   *sysroot,
                        &deployment_dfd, error))
     return FALSE;
 
+  /* We need to label the kernels */
+  g_autoptr(OstreeSePolicy) sepolicy = ostree_sepolicy_new_at (deployment_dfd, cancellable, error);
+  if (!sepolicy)
+    return FALSE;
+
   /* Find the kernel/initramfs/devicetree in the tree */
   g_autoptr(OstreeKernelLayout) kernel_layout = NULL;
   if (!get_kernel_from_tree (deployment_dfd, &kernel_layout,
@@ -1652,11 +1675,10 @@ install_deployment_kernel (OstreeSysroot   *sysroot,
     return FALSE;
   if (errno == ENOENT)
     {
-      if (!hardlink_or_copy_at (kernel_layout->boot_dfd,
-                                kernel_layout->kernel_srcpath,
-                                bootcsum_dfd, kernel_layout->kernel_namever,
-                                sysroot->debug_flags,
-                                cancellable, error))
+      if (!install_into_boot (sepolicy, kernel_layout->boot_dfd, kernel_layout->kernel_srcpath,
+                              bootcsum_dfd, kernel_layout->kernel_namever,
+                              sysroot->debug_flags,
+                              cancellable, error))
         return FALSE;
     }
 
@@ -1670,10 +1692,10 @@ install_deployment_kernel (OstreeSysroot   *sysroot,
         return FALSE;
       if (errno == ENOENT)
         {
-          if (!hardlink_or_copy_at (kernel_layout->boot_dfd, kernel_layout->initramfs_srcpath,
-                                    bootcsum_dfd, kernel_layout->initramfs_namever,
-                                    sysroot->debug_flags,
-                                    cancellable, error))
+          if (!install_into_boot (sepolicy, kernel_layout->boot_dfd, kernel_layout->initramfs_srcpath,
+                                  bootcsum_dfd, kernel_layout->initramfs_namever,
+                                  sysroot->debug_flags,
+                                  cancellable, error))
             return FALSE;
         }
     }
@@ -1685,10 +1707,10 @@ install_deployment_kernel (OstreeSysroot   *sysroot,
         return FALSE;
       if (errno == ENOENT)
         {
-          if (!hardlink_or_copy_at (kernel_layout->boot_dfd, kernel_layout->devicetree_srcpath,
-                                    bootcsum_dfd, kernel_layout->devicetree_namever,
-                                    sysroot->debug_flags,
-                                    cancellable, error))
+          if (!install_into_boot (sepolicy, kernel_layout->boot_dfd, kernel_layout->devicetree_srcpath,
+                                  bootcsum_dfd, kernel_layout->devicetree_namever,
+                                  sysroot->debug_flags,
+                                  cancellable, error))
             return FALSE;
         }
     }
index f490b69d421a4a849830d1bb31ad7b0e13b2a8f2..2ad34c3c7ecfdad25763561d70ac4eae5a06feee 100755 (executable)
@@ -29,4 +29,28 @@ for file in fstab passwd exports hostname sysctl.conf yum.repos.d \
     assert_streq "${current}" "${new}"
 done
 
+# Cleanup
 ostree admin undeploy 0
+
+cd /ostree/repo/tmp
+ostree checkout --fsync=0 -H ${host_commit} test-label
+rm test-label/usr/lib/ostree-boot/vmlinuz*
+rm test-label/usr/lib/ostree-boot/initramfs*
+cd test-label/usr/lib/modules/*
+rm initramfs.img
+echo new initramfs > initramfs.img
+cd -
+ostree commit --link-checkout-speedup --selinux-policy=test-label -b test-label --consume --tree=dir=test-label
+
+ostree admin deploy --karg-proc-cmdline test-label
+
+# This captures all of the boot entries; it'd be slightly annoying
+# to try to figure out the accurate one, so let's just ensure that at least
+# one entry is boot_t.
+# https://bugzilla.redhat.com/show_bug.cgi?id=1536991
+ls -Z /boot/ostree/*/ > bootlsz.txt
+assert_file_has_content_literal bootlsz.txt 'system_u:object_r:boot_t:s0 vmlinuz-'
+assert_file_has_content_literal bootlsz.txt 'system_u:object_r:boot_t:s0 initramfs-'
+
+ostree admin undeploy 0
+ostree refs --delete test-label